home *** CD-ROM | disk | FTP | other *** search
/ PC-Blue - MS DOS Public Domain Library / PC-Blue MS-DOS Public Domain Library - NYACC.iso / vol194 / kermasm.arc / MSCOMM.ASM < prev    next >
Encoding:
Assembly Source File  |  1985-11-14  |  21.3 KB  |  681 lines

  1. ; Edit history:
  2. ;
  3. ; [v2.28]
  4. ; Let debug packet display routines print packets with '$' in them,
  5. ; Fix timeout in inchr to work correctly
  6. ;   (from Edgar Butt, Univ. of Md.)
  7. ; Ignore packets which are too small
  8. ;   (from Greg Small, UC Berkeley)
  9. ; Added sleep routine
  10.  
  11.     public    data, spack, rpack, rpack5, portval, port1, port2, hierr
  12.     public    prtbase, nports, port3, port4, sleep
  13.     include msdefs.h
  14.  
  15. maxlp    equ    100        ; Use as number of times to loop (in inchr).
  16. true    equ    1
  17. false    equ    0
  18. mntrgl    equ    bufsiz/4    ; Low point = 1/4 of the way full.
  19. maxpack    equ    78H        ; largest packet we can handle
  20.  
  21. datas    segment    public 'datas'
  22.     extrn    flags:byte, trans:byte, pack:byte, count:word, xofsnt:byte
  23.  
  24. prtbase    label    byte
  25. port1    prtinfo    <0FFFH,0,defpar,1,0,defhand,floxon>
  26. port2    prtinfo    <0FFFH,0,defpar,1,0,defhand,floxon>
  27. port3     prtinfo    <0FFFH,0,defpar,1,0,defhand,floxon>
  28. port4    prtinfo    <0FFFH,0,defpar,1,0,defhand,floxon>
  29.     rept    portmax-4
  30.     prtinfo    <0FFFH,0,defpar,1,0,defhand,floxon>
  31.     endm
  32.  
  33. ;; systems with two ports can set portval to port1 or port2.
  34. ;; systems with more than two ports can set nports higher,
  35. ;; then set portval to the address prtbase+(#-1)*size prtinfo
  36. ;; where # is the desired port.
  37.  
  38. portval    dw    port1        ; Default is to use port 1.
  39. nports    db    2        ; # of known ports
  40. hierr    db    0        ; Non-ascii char (non-zero if yes).
  41. spmes    db    'Spack:  $'
  42. rpmes     db    'Rpack:  $'
  43. crlf    db      cr,lf,'$'
  44. infms0  db    'Waiting .....$'
  45. hibit    db    'Warning - Non Ascii char$'
  46. cemsg    db    'User intervention$'
  47. temp    dw    0
  48. tmp    db    ?,'$'
  49. prvtyp  db      0               ; Type of last packet sent. [27e]
  50. pktptr  dw    ?        ; Position in receive packet.
  51. incnt    dw    ?        ; Number of chars read in from port.
  52. loopct    db    ?        ; Loop counter.
  53. time     dw    ?        ; When we should timeout. 
  54.     dw    ?        ; Want a double word.
  55. packet  db    ?,?,?,?        ; Packet (data is part of it).
  56. data    db    5AH DUP(?)    ; Data and checksum field of packet.
  57. recpkt  db    maxpack DUP(?)    ; Receive packet storage (use the following).
  58.         db      ?,?,?,?         ; Space for '$' and other stuff.  
  59. crctab    dw    00000H
  60.     dw    01081H
  61.     dw    02102H
  62.     dw    03183H
  63.     dw    04204H
  64.     dw    05285H
  65.     dw    06306H
  66.     dw    07387H
  67.     dw    08408H
  68.     dw    09489H
  69.     dw    0A50AH
  70.     dw    0B58BH
  71.     dw    0C60CH
  72.     dw    0D68DH
  73.     dw    0E70EH
  74.     dw    0F78FH
  75.  
  76. crctb2    dw    00000H
  77.     dw    01189H
  78.     dw    02312H
  79.     dw    0329BH
  80.     dw    04624H
  81.     dw    057ADH
  82.     dw    06536H
  83.     dw    074BFH
  84.     dw    08C48H
  85.     dw    09DC1H
  86.     dw    0AF5AH
  87.     dw    0BED3H
  88.     dw    0CA6CH
  89.     dw    0DBE5H
  90.     dw    0E97EH
  91.     dw    0F8F7H
  92. datas    ends
  93.  
  94. code    segment    public
  95.     extrn    prtchr:near, clrbuf:near, outchr:near
  96.     extrn    sppos:near, stpos:near, biterr:near, intmsg:near
  97.     extrn    clearl:near, rppos:near, errpack:near, prtscr:near
  98.     assume     cs:code, ds:datas
  99.  
  100. ;    Packet routines
  101.  
  102. ; Send_Packet
  103. ; This routine assembles a packet from the arguments given and sends it
  104. ; to the host.
  105. ;
  106. ; Expects the following:
  107. ;    AH     - Type of packet (D,Y,N,S,R,E,F,Z,T)
  108. ;    ARGBLK - Packet sequence number
  109. ;    ARGBK1 - Number of data characters
  110. ; Returns: +1 always
  111.  
  112. SPKT    PROC    NEAR
  113.  
  114. spack:     push ax            ; Save the packet type.
  115.         mov prvtyp,ah           ; Remember packet type. [27e]
  116.     call clrbuf        ; Clear the input buffer. [20e]
  117.     mov bx,offset packet    ; Get address of the send packet.
  118.     mov ah,trans.ssoh    ; Get the start of header char.
  119.     mov [bx],ah        ; Put in the packet.
  120.     inc bx            ; Point to next char.
  121.     mov ax,pack.argbk1    ; Get the number of data chars.
  122.     xchg ah,al
  123.     mov al,trans.chklen    ; Length of checksum.
  124.     dec al            ; Extra length of checksum.
  125.     add ah,' '+3        ; Real packet character count made printable.
  126.     add ah,al        ; Account for checksum length in count.
  127.     mov [bx],ah        ; Put in the packet.
  128.     inc bx            ; Point to next char.
  129.     mov ch,0        ; For the 16 bit checksum.
  130.     mov cl,ah        ; Start the checksum.
  131.     mov ax,pack.argblk    ; Get the packet number.
  132.     add al,' '        ; Add a space so the number is printable.
  133.     mov [bx],al        ; Put in the packet.
  134.     inc bx            ; Point to next char.
  135.     add cx,ax        ; Add the packet number to the checksum.
  136.     pop ax            ; Get the packet type.
  137.     mov [bx],ah        ; Put in the packet.
  138.     inc bx            ; Point to next char.
  139.     mov al,0
  140.     xchg ah,al
  141.     add cx,ax        ; Add the type to the checksum.
  142.     mov dx,pack.argbk1    ; Get the packet size.
  143. spack2: cmp dx,0        ; Are there any chars of data?
  144.      jz spack3        ;  No, finish up.
  145.     dec dx            ; Decrement the char count.
  146.     mov al,[bx]        ; Get the next char.
  147.     inc bx            ; Point to next char.
  148.     mov ah,0
  149.     add cx,ax        ; Add the char to the checksum.
  150.     cmp al,0
  151.     jns spack2
  152.     cmp hierr,0ffH        ; Printed message already?
  153.     je spack2        ; Yes, then that's it.
  154.     push bx
  155.     push cx
  156.     push dx
  157.     call biterr
  158.     pop dx
  159.     pop cx
  160.     pop bx
  161.     mov hierr,0FFH        ; set err flag. 
  162.     jmp spack2        ; Go try again.
  163. spack3:    cmp trans.chklen,2    ; What kind of checksum are we using.
  164.     je spackx        ; 2 characters.
  165.     jg spacky        ; 3 characters.
  166.     mov ah,cl        ; 1 char: get the character total.
  167.     mov ch,cl        ; Save here too (need 'cl' for shift).
  168.     and ah,0C0H        ; Turn off all but the two high order bits.
  169.     mov cl,6
  170.     shr ah,cl        ; Shift them into the low order position.
  171.     mov cl,ch
  172.     add ah,cl        ; Add it to the old bits.
  173.     and ah,3FH        ; Turn off the two high order bits.  (MOD 64)
  174.     add ah,' '        ; Add a space so the number is printable.
  175.     mov [bx],ah        ; Put in the packet.
  176.     inc bx            ; Point to next char.
  177.     jmp spackz        ; Add EOL char.
  178. spacky:    mov al,0        ; Get a null.
  179.     mov [bx],al        ; To determine end of buffer.
  180.     push bx            ; Don't lose our place.
  181.     mov bx,offset packet+1    ; First checksummed character.
  182.     call crcclc        ; Calculate the CRC.
  183.     pop bx
  184.     push cx
  185.     mov ax,cx        ; Manipulate it here.
  186.     and ax,0F000H        ; Get 4 highest bits.
  187.     mov cl,4
  188.     shr ah,cl        ; Shift them over 4 bits.
  189.     add ah,' '        ; Make printable.
  190.     mov [bx],ah        ; Add to buffer.
  191.     inc bx
  192.     pop cx            ; Get back checksum value.
  193. spackx:    push cx            ; Save it for now.
  194.     and cx,0FC0H        ; Get bits 6-11.
  195.     mov ax,cx
  196.     mov cl,6
  197.     shr ax,cl        ; Shift them bits over.
  198.     add al,' '        ; Make printable.
  199.     mov [bx],al        ; Add to buffer.
  200.     inc bx
  201.     pop cx            ; Get back the original.
  202.     and cx,003FH        ; Get bits 0-5.
  203.     add cl,' '        ; Make printable.
  204.     mov [bx],cl        ; Add to buffer.
  205.     inc bx
  206. spackz:    cmp flags.debug,0    ; debug mode.
  207.     je spack4
  208.     push bx            ; save end of packet position
  209.     call sppos
  210.     call clearl
  211.     mov dx,offset crlf
  212.     mov ah,prstr
  213.     int dos
  214.     call clearl        ; clear spack line and line below
  215.     call sppos
  216.     mov ah,prstr
  217.     mov dx,offset spmes
  218.     int dos            ; print "spack:" message
  219.     mov di,offset packet    ; address of packet
  220.     pop cx
  221.     push cx
  222.     sub cx,di        ; calculate length of string
  223.     call prtscr
  224.     pop bx            ; restore end of string pointer
  225. spack4:    mov ah,trans.seol    ; Get the EOL the other host wants.
  226.     mov [bx],ah        ; Put in the packet.
  227.     inc bx            ; Point to next char.
  228.     mov ah,0        ; Get a null.
  229.     mov [bx],ah        ; Put in the packet.
  230.     call outpkt        ; Call the system dependent routine.
  231.      jmp r
  232.     jmp rskp
  233. SPKT    ENDP 
  234.  
  235. ;    Write out a packet.
  236.  
  237. OUTPKT  PROC    NEAR
  238.     mov dh,trans.spad    ; Get the number of padding chars.
  239. outpk2: dec dh
  240.     cmp dh,0
  241.     jl outpk3        ; If none left proceed.
  242.     mov ah,trans.spadch    ; Get the padding char.
  243.     push dx            ; save loop counter
  244.     call outchr        ; Output it.
  245.      pop dx
  246.      ret            ; we failed...
  247.     jmp outpk2
  248. outpk3: mov bx,offset packet    ; Point to the packet.
  249. outlup: mov ah,[bx]        ; Get the next character.
  250.     cmp ah,0        ; Is it a null?
  251.     jnz outlp2
  252.     jmp rskp
  253. outlp2: call outchr        ; Output the character.
  254.      jmp r
  255.     inc bx            ; Increment the char pointer.
  256.     jmp outlup
  257. OUTPKT  ENDP
  258.  
  259. ; Calculate the CRC.  Returns the CRC in CX.  Destroys: BX, AX.
  260. crcclc:    push dx
  261.     push si
  262.     mov dx,0        ; Initial CRC value is 0.
  263. crc0:    mov al,[bx]        ; Get the first char of the string.
  264.     cmp al,0        ; If null, then we're done.
  265.     je crc1
  266.     inc bx
  267.     xor al,dl        ; Xor input with lo order byte of CRC.
  268.     mov ah,al        ; Get a copy.
  269.     and ah,0F0H        ; Get hi 4 bits.
  270.     mov cl,4
  271.     shr ah,cl        ; Right justify.
  272.     and al,0FH        ; Get lo 4 bits.
  273.     push bx
  274.     mov si,offset crctb2    ; Low portion of CRC factor.
  275.     mov bh,0
  276.     mov bl,al
  277.     add bl,al        ; Get word index.
  278.     mov cx,[si+bx]        ; Low portion.
  279.     mov si,offset crctab    ; High portion of CRC factor.
  280.     mov bh,0
  281.     mov bl,ah
  282.     add bl,ah        ; Get word index.
  283.     mov bx,[si+bx]
  284.     xor bx,cx        ; Add the two.
  285.     mov cl,8
  286.     shr dx,cl        ; Shift CRC 8 bits to the right.
  287.     xor dx,bx        ; XOR table value and CRC.
  288.     pop bx            ; Retrieve index.
  289.     jmp crc0
  290. crc1:    mov cx,dx        ; Return it in CX.
  291.     pop si
  292.     pop dx
  293.     ret
  294.  
  295. ; Receive_Packet
  296. ; This routine waits for a packet arrive from the host.  It reads
  297. ; chars until it finds a SOH.
  298.  
  299. RPACK    PROC    NEAR
  300. rpack5: call inpkt        ; Read up to a carriage return.
  301.      jmp r            ;  Return bad.
  302. rpack0: call getchr        ; Get a character.
  303.      jmp r            ;  Hit the carriage return, return bad.
  304.     cmp al,trans.rsoh    ; Is the char the start of header char?
  305.      jne rpack0        ;  No, go until it is.
  306. rpack1: call getchr        ; Get a character.
  307.      jmp r            ;  Hit the carriage return, return bad.
  308.     cmp al,trans.rsoh    ; Is the char the start of header char?
  309.      jz rpack1        ;  Yes, then go start over.
  310.     mov ch,0        ; For 16-bit checksum.
  311.     mov cl,al        ; Start the checksum.
  312.     mov ah,0
  313.     mov pack.argbk1,ax    ; Save the data count.
  314.     call getchr        ; Get a character.
  315.      jmp r            ;  Hit the carriage return, return bad.
  316.     cmp al,trans.rsoh    ; Is the char the start of header char?
  317.      jz rpack1        ;  Yes, then go start over.
  318.     mov ah,0
  319.     add cx,ax        ; Add it to the checksum.
  320.     sub al,' '        ; Get the real packet number.
  321.     mov ah,0
  322.     mov pack.argblk,ax    ; Save the packet number.
  323.     call getchr        ; Get a character.
  324.      jmp r            ;  Hit the carriage return, return bad.
  325.     cmp al,trans.rsoh    ; Is the char the start of header char?
  326.      jz rpack1        ;  Yes, then go start over.
  327.     mov ah,0
  328.     mov temp,ax        ; Save the message type. [11]
  329.         mov bp,portval          ; Point to current port structure. [27e]
  330.         cmp ds:[bp].ecoflg,0    ; Is the host echoing? [27e]
  331.         jne rpak11              ; No, packets not echoed. [27e]
  332.         cmp al,prvtyp           ; Packet type same as last sent? [27e]
  333.         je rpack5               ; Yes, chuck echoed packet. [27e]
  334. rpak11:    add cx,ax        ; Add it to the checksum.
  335. ; Start of change.
  336. ; Now determine block check type for this packet.  Here we violate the layered
  337. ; nature of the protocol by inspecting the packet type in order to detect when
  338. ; the two sides get out of sync.  Two heuristics allow us to resync here:
  339. ;   a. An S packet always has a type 1 checksum.
  340. ;   b. A NAK never contains data, so its block check type is LEN-2. 
  341.     push cx
  342.     mov cl,al
  343.     mov ax,pack.argbk1    ; Get back the size.
  344.     sub al,34        ; unchar(len) - 2, for SEQ & TYPE fields.
  345.     mov ah,trans.chklen    ; Checksum length we expect.
  346.     cmp cl,'S'        ; Is this an "S" packet?
  347.     jne rpk0        ; Nope.
  348.     mov ah,1        ; Yes, use 1 char checksum.
  349. rpk0:    cmp cl,'N'        ; Is this a NAK?
  350.     jne rpk1        ; Nope.
  351.     mov ah,al        ; So, len - 2 is checksum type.
  352. rpk1:    mov trans.chklen,ah    ; Then, this is the chksum length.
  353.     sub al,ah        ; Real size of data.
  354.     mov dh,al        ; Need it here.
  355.     mov ah,0
  356.     mov pack.argbk1,ax    ; And here.
  357.     pop cx    
  358. ; End of change.
  359.     mov bx,offset data    ; Point to the data buffer.
  360. rpack2: dec dh            ; Any data characters?
  361.      js rpack3        ;  If not go get the checksum.
  362.     call getchr        ; Get a character.
  363.      jmp r            ;  Hit the carriage return, return bad.
  364.     cmp al,trans.rsoh    ; Is the char the start of header char?
  365.      jnz rpak2a
  366.     jmp rpack1        ;  Yes, then go start over.
  367. rpak2a:    mov [bx],al        ; Put the char into the packet.
  368.     inc bx            ; Point to the next character.
  369.     mov ah,0
  370.     add cx,ax        ; Add it to the checksum.
  371.     jmp rpack2        ; Go get another.
  372. rpack3: call getchr        ; Get a character.
  373.      jmp r            ;  Hit the carriage return, return bad.
  374.     cmp al,trans.rsoh    ; Is the char the start of header char?
  375.      jnz rpk3x
  376.      jmp rpack1        ;  Yes, then go start over.
  377. rpk3x:    sub al,' '        ; Turn the char back into a number.
  378.     cmp trans.chklen,2    ; What checksum length is in use.
  379.     je rpackx        ; Two character checksum.
  380.     jg rpacky        ; Three character CRC.
  381.     mov dh,cl        ; 1 char - get the character total.
  382.     and dh,0C0H        ; Turn off all but the two high order bits.
  383.     mov ch,cl
  384.     mov cl,6
  385.     shr dh,cl        ; Shift them into the low order position.
  386.     mov cl,ch
  387.     add dh,cl        ; Add it to the old bits.
  388.     and dh,3FH        ; Turn off the two high order bits.  (MOD 64)
  389.     cmp dh,al        ; Are they equal?
  390.      jz rpack4        ; If so finish up.
  391.     jmp rpack6        ; No, we fail.
  392. rpacky:    mov tmp,al        ; Save value from packet here.
  393.     mov ah,0        ; Three character CRC.
  394.     push bx
  395.     mov bx,pktptr        ; Where we are in the packet.
  396.     dec bx
  397.     mov [bx],ah        ; Add null to signify end of buffer.
  398.     mov bx,offset recpkt+1    ; Where data for CRC is.
  399.     call crcclc        ; Calculate the CRC and put into CX.
  400.     pop bx
  401.     push cx
  402.     mov ax,cx        ; Manipulate it here.
  403.     and ax,0F000H        ; Get 4 highest bits.
  404.     mov cl,4
  405.     shr ah,cl        ; Shift them over 4 bits.
  406.     pop cx            ; Get back checksum value.
  407.     cmp ah,tmp        ; Is what we got == what we calculated?
  408.     jne rpack6
  409.     call getchr        ; Get next character of checsum.
  410.      jmp r            ; Failed.    
  411.     cmp al,trans.rsoh    ; Restarting?
  412.      jz rpack7
  413.     sub al,' '        ; Get back real value.
  414. rpackx:    mov tmp,al        ; Save here for now.
  415.     push cx            ; Two character checksum.
  416.     and cx,0FC0H        ; Get bits 6-11.
  417.     mov ax,cx
  418.     mov cl,6
  419.     shr ax,cl        ; Shift them bits over.
  420.     pop cx            ; Get back the original.
  421.     cmp al,tmp        ; Are they equal?
  422.      jne rpack6        ; No, we fail.
  423.     call getchr        ; Get last character of checsum.
  424.      jmp r            ; Failed.    
  425.     cmp al,trans.rsoh    ; Restarting?
  426.      jz rpack7
  427.     sub al,' '        ; Get back real value.    
  428.     and cx,003FH        ; Get bits 0-5.
  429.     cmp al,cl        ; Do the last chars match?
  430.     jne rpack6
  431. rpack4: mov ah,0
  432.     mov [bx],ah        ; Put a null at the end of the data.
  433.     mov ax,temp        ; Get the type.   [11]
  434.     xchg al,ah        ; Packet type should be in AH.
  435.     jmp rskp
  436. rpack6:    ret
  437. rpack7:    jmp rpack1        ; For the jump out of range.
  438. RPACK    ENDP
  439.  
  440.  
  441. INPKT    PROC    NEAR
  442.     mov bl,flags.cxzflg    ; Remember original value. [20b]
  443.     mov tmp,bl        ; Store it here. [20b]
  444. inpkt0:    call inchr        ; Get a character. [27a]
  445.      jmp inpkt8        ;  Return failure. [27a]
  446.      nop            ;  Make it three bytes long. [27a]
  447.     cmp ah,trans.rsoh    ; Is it SOH char? [27a]
  448.     jne inpkt0        ; No hold out for SOH. [27a]
  449. inpkt1:    mov bx,offset recpkt    ; Point to the beginning of the packet.
  450.     mov incnt,0
  451.     mov [bx],ah        ; Add SOH to buffer. [27a]
  452.     inc bx            ; Increment pointer. [27a]
  453.     inc incnt        ; Increment counter. [27a]
  454. inpkt2:    call inchr        ; Get a character.
  455.      jmp inpkt8        ;  Return failure. [20b]
  456.      nop            ;  Make it three bytes long. [20b] 
  457.     cmp ah,trans.rsoh    ; Starting over again? [27a]
  458.     je inpkt1
  459.     mov [bx],ah        ; Put the char in the packet.
  460.     inc bx
  461.     inc incnt
  462.     cmp ah,trans.reol    ; Is it the EOL char?
  463.     je inpkt3        ; ended by eol, keep going
  464.     cmp incnt,maxpack    ; is it too big?
  465.     jbe inpkt2        ; no, keep going
  466.     jmp inpkt1        ; else just start over
  467. inpkt3:    cmp incnt,5        ; Ignore packets which are too small
  468.     jbe inpkt0
  469.     mov bp,portval
  470.     cmp ds:[bp].hndflg,0    ; Waiting for handshake?
  471.     jz inpkt5        ; If not then proceed.
  472. inpkt4: call inchr        ; Wait for the turn around char.
  473.      jmp inpkt8        ;  Return failure. [20b]
  474.      nop            ;  Make it three bytes long.  [20b]
  475.     cmp ah,trans.rsoh    ; Start of packet? [27a]
  476.     je inpkt1        ; Yes go start over. [27a]
  477.     mov bp,portval
  478.     cmp ah,ds:[bp].hands    ; Is it the IBM turn around character?
  479.     jne inpkt4        ; If not, go until it is.
  480. inpkt5:    cmp flags.debug,0    ; In debug mode?
  481.     je inpkt6
  482.         push bx                 ; save character pointer
  483.         call rppos
  484.         call clearl
  485.         mov dx,offset crlf
  486.         mov ah,prstr
  487.         int dos
  488.         call clearl             ; clear debug line and line beneath
  489.         call rppos              ; Reposition cursor.
  490.         mov ah,prstr
  491.         mov dx,offset rpmes
  492.         int dos
  493.         mov di,offset recpkt    ; buffer address
  494.         pop cx
  495.         sub cx,di        ; length of buffer
  496.         call prtscr             ; display packet
  497. inpkt6:    mov bx,offset recpkt
  498.     mov pktptr,bx        ; Save the packet pointer.
  499.     mov bl,tmp        ; Get the original value. [20b]
  500.     cmp bl,flags.cxzflg    ; Did ¬X/¬Z flag change? [20b]
  501.     je inpkt7        ; If not, just return.  [20b]
  502.     cmp flags.cxzflg,'E'    ; Error packet?
  503.     je inpkt9
  504.     call intmsg         ; Else, say we saw the interrupt. [20b]
  505. inpkt7: jmp rskp        ; If so we are done.
  506. inpkt8:    cmp flags.cxzflg,'C'    ; Did the user type a ¬C? [25]
  507.     jne inpkt9
  508.     mov pack.state,'A'
  509.     ret
  510. inpkt9:    cmp flags.cxzflg,'E'    ; How about ¬E?
  511.     jne inpk10        ; No just go on.
  512.     mov bx,offset cemsg    ; Null message for error packet.
  513.     call errpack
  514.     mov pack.state,'A'
  515.     ret
  516. inpk10:    mov bl,tmp        ; Get the original value. [20b]
  517.     cmp bl,flags.cxzflg    ; Did ¬X/¬Z flag change? [20b]
  518.     je inpk11        ; If not, just return failure.  [20b]
  519.     call intmsg         ; Else, say we saw the interrupt. [20b]
  520. inpk11:    jmp r
  521. INPKT    ENDP
  522.  
  523. ; sleep for the # of seconds in al
  524. sleep    proc    near
  525.     saveac    <bx,cx,dx>
  526.     push    ax        ; save argument
  527.     mov    ah,gettim
  528.     int    dos        ; get current time
  529.     pop    bx        ; restore desired # of seconds
  530.     add    dh,bl        ; add # of seconds
  531. sleep1:    cmp    dh,60        ; too big for seconds?
  532.     jb    sleep2        ; no, keep going
  533.     sub    dh,60        ; yes, subtract a minute
  534.     inc    cl        ; and make up for it here
  535.     cmp    cl,60        ; did minutes overflow?
  536.     jb    sleep1        ; no, check seconds again
  537.     sub    cl,60        ; else take away an hour
  538.     inc    ch        ; add it back here
  539.     jmp    sleep1        ; and keep checking
  540. sleep2:    mov    time,cx
  541.     mov    time+2,dx    ; store desired ending time
  542. sleep3:    mov    ah,gettim    ; get time
  543.     int    dos        ; bug dos
  544. ; adjust time when times are before and after midnight.
  545.     cmp    ch,0        ; is ending time between 0:00 and 1:00?
  546.     jne    sleep4        ; no, keep going
  547.     cmp    byte ptr time+1,23 ; is desired time after 23:00?
  548.     jne    sleep4        ; no, go on
  549.     mov    ch,24        ; otherwise set current hour to 24
  550. sleep4:    cmp    cx,time        ; check hours and minutes
  551.     jb    sleep3
  552.     ja    sleep5        ; over limit, time to exit
  553.     cmp    dx,time+2    ; same, check seconds and fraction
  554.     jb    sleep3        ; below, keep looking
  555. sleep5:    ret            ; else just return
  556. sleep    endp
  557.  
  558.  
  559. inchr:    cmp flags.timflg,0    ; Are timeouts turned off.
  560.     je inchr1        ; Yes, so skip this stuff.
  561.     cmp trans.stime,0    ; Don't time out?
  562.     je inchr1        ; Yes, so skip this stuff.
  563.     mov loopct,0        ; Use to check for timeout.
  564.     mov ah,gettim        ; Get the time.
  565.     int dos
  566.     add dh,trans.stime    ; add timeout to seconds
  567. inch01:    cmp dh,60        ; seconds overflowed?
  568.     jb inch02        ; no, break loop
  569.     sub dh,60
  570.     inc cl            ; add one minute
  571.     cmp cl,60        ; did this make minutes overflow?
  572.     jb inch01        ; no, check seconds again (should just divide)
  573.     sub cl,60
  574.     inc ch            ; add one hour
  575.     jmp inch01        ; and check seconds again
  576. inch02:    mov time,cx
  577.     mov time+2,dx        ; store ending time now.
  578. inchr1:    call prtchr        ; Is there a character to read?
  579.      jmp inchr6        ; Got one.
  580.     mov dl,0FFH        ; To read in a char.
  581.     mov ah,dconio        ; Is a char on the console?
  582.     int dos
  583.     jz inchr2        ; If not go look for another char.
  584.     mov ah,al 
  585.     cmp ah,cr        ; Is it a carriage return?
  586.     je inchr5        ; If yes, then leave.
  587.     cmp ah,'Z'-100O        ; Control-Z? [20b]
  588.     je inchr4        ; Yes - flag it. [20b]
  589.     cmp ah,'X'-100O        ; Control-X? [20b]
  590.     je inchr4        ; Yes - flag it. [20b]
  591.     cmp ah,'E'-100O        ; Control-E?
  592.     je inchr4        ; Flag it and get rest of packet.
  593.     cmp ah,'C'-100O        ; Control-C? [25]
  594.     jne inchr2        ; No, then wait for input. [25]
  595.     add ah,100O        ; Make it printable. [25]
  596.     mov flags.cxzflg,ah    ; Save it. [25]
  597.     ret            ; Return right away. [25]
  598. inchr2:    cmp flags.timflg,0    ; Are timeouts turned off?
  599.     je inchr1        ; Yes, just check for more input.
  600.     cmp trans.stime,0    ; Doing time outs?
  601.     je inchr1        ; No, just go check for more input.
  602.     inc loopct
  603.     cmp loopct,maxlp    ; Times to go without checking time.
  604.     jne inchr1        ; Don't check yet.
  605.     mov ah,gettim        ; Get the current time.
  606.     int dos
  607. ; adjust time when times are before and after midnight
  608. ; note: this won't work for timeouts which start before
  609. ; midnight and are more than an hour (not likely!).
  610.     cmp ch,0        ; is ending time between 00:00 and 1:00?
  611.     jne inch21        ; no, can just compare times
  612.     cmp byte ptr time+1,23    ; is desired hour after 23:00?
  613.     jne inch21        ; no, just compare them
  614.     mov ch,24        ; otherwise set current hour to 24 for wrap
  615. inch21:    cmp cx,time        ; check hours and minutes
  616.     jb inchr3        ; under limit, keep looking
  617.     ja inchr5        ; over limit, time out
  618.     cmp dx,time+2        ; same, compare seconds and fraction
  619.     jae inchr5        ; over limit, time out
  620. ; fall thru if time hasn't occurred yet.
  621. inchr3:    mov loopct,0        ; Reset counter.
  622.     jmp inchr1
  623. inchr4: add ah,100O        ; Make it printable. [20b]
  624.     mov flags.cxzflg,ah    ; Remember what we saw. [20b]
  625.     jmp inchr2        ; Continue getting input. [20b]
  626. inchr5:    ret
  627. inchr6: mov ah,al
  628.     mov bp,portval        ; Point to current port structure.
  629.     cmp ds:[bp].parflg,parnon    ; Is the parity none?    [10]
  630.     je inchr7        ; We're done.        [10]
  631.     and ah,7FH        ; Turn off the parity bit.
  632. inchr7:    cmp ds:[bp].floflg,0    ; Doing any flow control?
  633.     jne inchr8        ; Yes, check it out.
  634.     jmp rskp        ; No, just return the data.
  635. inchr8:    cmp xofsnt,true        ; Have we sent flow char (XOFF)?
  636.     je inchr9        ; Yes.
  637.     jmp rskp        ; No, just return.
  638. inchr9:    cmp count,mntrgl    ; Under the low trigger point?
  639.     jb inchra        ; Yes.
  640.     jmp rskp        ; No, just return.
  641. inchra:    push ax
  642.     mov bp,portval
  643.     mov ax,ds:[bp].flowc    ; Get flow control char (AH = XON, AL = XOFF).
  644.     call outchr        ; Send it (XON).
  645.     mov xofsnt,false    ; Turn off the flag.
  646.     pop ax
  647.     jmp rskp        ; Return the character.
  648.  
  649. ; Return next character in AL.
  650. GETCHR  PROC    NEAR
  651.     push bx
  652.     mov bx,pktptr        ; Get the packet pointer.
  653.     mov al,[bx]        ; Get the char.
  654.     inc bx
  655.     mov pktptr,bx
  656.     pop bx            ; Restore BX.
  657.     cmp al,trans.reol    ; Is it the EOL char?
  658.     jne getcr2        ; If not return retskp.
  659.     ret            ; If so return failure.
  660. getcr2: jmp rskp
  661. GETCHR  ENDP
  662.  
  663. ; Jumping to this location is like retskp.  It assumes the instruction
  664. ;   after the call is a jmp addr.
  665.  
  666. RSKP    PROC    NEAR
  667.     pop bp
  668.     add bp,3
  669.     push bp
  670.     ret
  671. RSKP    ENDP
  672.  
  673. ; Jumping here is the same as a ret.
  674.  
  675. R    PROC    NEAR
  676.     ret
  677. R    ENDP
  678.  
  679. code    ends
  680.     end
  681.